﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Ext.Direct.Mvc
{
    public class DirectResult : JsonResult
    {
        public JsonSerializerSettings Settings {
            get;
            set;
        }

        public IList<JsonConverter> Converters {
            get;
            set;
        }

        public override void ExecuteResult(ControllerContext context) {
            if (context == null) {
                throw new ArgumentNullException("context");
            }

            HttpResponseBase httpResponse = context.HttpContext.Response;

            var directRequest = context.HttpContext.Items[DirectRequest.DirectRequestKey] as DirectRequest;

            if (directRequest == null) {
                throw new NullReferenceException("DirectRequest is null.");
            }

            var directResponse = new DirectResponse(directRequest) { Result = Data };

            if (directResponse.IsUpload) {
                // File upload request requires special response
                httpResponse.ContentType = "text/html";
                string s = "<html><body><textarea>{0}</textarea></body></html>";
                httpResponse.Write(String.Format(s, JsonConvert.SerializeObject(directResponse).Replace("&quot;", "\\&quot;")));
            } else {
                if (!String.IsNullOrEmpty(ContentType)) {
                    httpResponse.ContentType = ContentType;
                } else {
                    httpResponse.ContentType = "application/json";
                }

                if (ContentEncoding != null) {
                    httpResponse.ContentEncoding = ContentEncoding;
                }

                var serializer = JsonSerializer.Create(this.Settings);
                if (this.Converters != null) {
                    foreach (JsonConverter converter in this.Converters) {
                        serializer.Converters.Add(converter);
                    }
                }
                // Default DateTime converter.
                // Because the first DateTime converter in the collection is used when serializing,
                // this converter does not override the one specified by the user since it's added last.
                serializer.Converters.Add(new JavaScriptDateTimeConverter());
                serializer.Serialize(httpResponse.Output, directResponse);
            }
        }
    }
}
